package unisannio.fm.interactive;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;


import org.unisannio.remote.FactoryRemote;
import org.unisannio.remote.RemoteBroadcaster;
import org.unisannio.util.Converter;
import org.unisannio.util.ServiceInfo;


import unisannio.fm.R;
import unisannio.fm.util.MultiSpinner;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class HelpMeActivity extends Activity {
	
	private static final String actionBase="unisannio.fm.";
	public static final String responseKey="risposta";
	public static final String questionKey="domanda";
	public static final String preferenceName="HelpPrefName";
	public static final String superpeer="SuperPeerAddress";
	public static Handler handler=new Handler();
	public static RemoteBroadcaster remoteBroadcaster;
	public static Bundle total=new Bundle();
	private final int port=5588; //tutti i peer sono registrati sulla stessa porta
	
	private Button help,imhere;
	private MultiSpinner multiSpinner;
	private ArrayList<ResponseReceiver> rrList;
	private ArrayList<QuestionReceiver> qrList;
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (checkConnection()){
        	this.registraPeer();
        	SharedPreferences pref=getSharedPreferences(preferenceName, 0);
        	String superpeerAddress=pref.getString(superpeer, null);
        	if (superpeerAddress!=null)
        		remoteBroadcaster.setServer(superpeerAddress);
        }
        
        
        

        
        setContentView(R.layout.main);
        help=(Button) findViewById(R.id.buttonHelp);
        imhere=(Button) findViewById(R.id.buttonImhere);
        
        multiSpinner = (MultiSpinner) findViewById(R.id.multispinner);
        ArrayList<String> items=this.getTopics();
//        ArrayList<String> items=new ArrayList<String>();
//        items.add("Photography");
//        items.add("Computer Science");
//        items.add("Apple");
//        items.add("Video");
        multiSpinner.setItems(items, "First of all, choose your interest");
        multiSpinner.setCallbackActivity(this);
        
        rrList=new ArrayList<ResponseReceiver>();
        qrList=new ArrayList<QuestionReceiver>();
    
        help.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View arg0) {
				ArrayList<String> selected=multiSpinner.getSelected();
				//DIALOG CON IMMISSIONE DOMANDA
				if (remoteBroadcaster!=null){
					sendQuestion();
				}
				
				else {Toast toast=Toast.makeText(HelpMeActivity.this, "Impossible to communicate.\nCheck your data connection.", Toast.LENGTH_LONG);
				toast.show();
				}
			}
		});
        
        imhere.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
				HelpMeActivity.this.registraReceivers(multiSpinner.getSelected(),false);
				
				String action=actionBase+"Apple";
				Intent intent=new Intent(action);
				intent.putExtra(responseKey, "stringa di prova - action: Apple");
				HelpMeActivity.this.sendBroadcast(intent);
				action=actionBase+"Video";
				intent=new Intent(action);
				intent.putExtra(responseKey, "stringa di prova - action:Video");
				HelpMeActivity.this.sendBroadcast(intent);
			}
		});
        
        this.setButtons(multiSpinner.getSelected().size()>0);
        
        if (!isServerSet()){
        	this.setButtons(false);
        }
    
    }
    
    
    
    private ArrayList<String> getTopics() {
    	ArrayList<String> topics = new ArrayList<String>();
		try {
			Resources res=getResources();
			InputStream fis=res.openRawResource(R.raw.topics);
			BufferedReader br=new BufferedReader(new InputStreamReader(fis));
			String curr=br.readLine();
			while(curr!=null && curr!=""){
				topics.add(curr);
				curr=br.readLine();
			}
		} catch (NotFoundException e) {
			e.printStackTrace();
			return topics;
		} catch (IOException e) {
			e.printStackTrace();
			return topics;
		}
		return topics;
	}



	protected void sendQuestion() {
		LayoutInflater inflater=LayoutInflater.from(this);
		View addView = inflater.inflate(R.layout.question, null);
		final QuestionDialogWrapper wrapper = new QuestionDialogWrapper(addView);
		new AlertDialog.Builder(this)
			.setTitle("Ask a question")
			.setView(addView)
			.setNegativeButton("Discard", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					
				}
			})
			.setPositiveButton("SEND", new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog, int which) {
					//su SEND invia i vari pacchetti alle varie actions registrate
					processSend(wrapper);
				}
			})
			.show();
	}



	protected void processSend(QuestionDialogWrapper wrapper) {
		if (remoteBroadcaster!=null){
			String question=wrapper.getQuestion();
			Bundle initialExtras=new Bundle();
			initialExtras.putString(questionKey, question);
			ArrayList<String> interessi=multiSpinner.getSelected();
			ResponseReceiver rr=(ResponseReceiver) this.registraReceivers(interessi,true);
			Intent intent;
			String action;
			for (String curr : interessi) {
				action=actionBase+curr;
				intent=new Intent(action);
				remoteBroadcaster.sendRemoteOrderedBroadcast(intent, null, rr, null, 0, null, initialExtras);
			}
		}
		
	}



	private void registraPeer() {
		FactoryRemote factory=new FactoryRemote();
		remoteBroadcaster=factory.getRemoteBroadcaster(this, port);
	}



	private BroadcastReceiver registraReceivers(ArrayList<String> interest,boolean domanda){
    	if (domanda){
    		ResponseReceiver rr=new ResponseReceiver();
    		rrList.add(rr);
    		for (Iterator<String> iterator = interest.iterator(); iterator.hasNext();) {
    			String curr = (String) iterator.next();
    			String newAction=actionBase+curr;
    			getApplicationContext().registerReceiver(rr,new IntentFilter(newAction));
    			rr.setActive(true);
    		}
    		return rr;
    	}
    	else {
		QuestionReceiver qr=new QuestionReceiver();
    	ServiceInfo sinfo=new ServiceInfo();
    	qrList.add(qr);
    	for (Iterator<String> iterator = interest.iterator(); iterator.hasNext();) {
			String curr = (String) iterator.next();
			String newAction=actionBase+curr;
			getApplicationContext().registerReceiver(qr,new IntentFilter(newAction));
			qr.setActive(true);
			sinfo.addDescriptor(newAction, curr, null, ServiceInfo.BROADCAST_RECEIVER);
			remoteBroadcaster.sendToSuperPeer(sinfo, Converter.PUBLISH);
		}
    		return qr;
    	}
    }
    
    
    
    
    
	class QuestionDialogWrapper {
		EditText questionField=null;
		View base=null;
		
		QuestionDialogWrapper(View base){
			this.base=base;
			questionField=(EditText)base.findViewById(R.id.questionField);
			
		}
		
		String getQuestion(){
			return(getQuestionField().getText().toString());
		}

		private EditText getQuestionField() {
			if (questionField==null) {
				questionField=(EditText)base.findViewById(R.id.questionField);
			}
			return questionField;
		}
	}
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		boolean result =super.onCreateOptionsMenu(menu);
//		MenuItem indirizzi=menu.add(Menu.NONE,1,1,"Indirizzi");
//		indirizzi.setIcon(android.R.drawable.ic_menu_agenda);
		MenuItem config=menu.add(Menu.NONE,2,2,"Connection configuration");
		config.setIcon(android.R.drawable.ic_menu_manage);
		MenuItem indirizzi=menu.add(Menu.NONE,1,1,"Delete selected interest");
		indirizzi.setIcon(R.drawable.ic_menu_clear_playlist);
		MenuItem dafile=menu.add(Menu.NONE,3,3,"Read saved answers");
		dafile.setIcon(android.R.drawable.ic_menu_save);
		MenuItem eliminaRR=menu.add(Menu.NONE,4,4,"Stop answers!");
		eliminaRR.setIcon(R.drawable.ic_menu_stop);
		MenuItem emiminaQR=menu.add(Menu.NONE,5,5,"I'm not here anymore");
		emiminaQR.setIcon(R.drawable.ic_menu_block);
		return result;
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		setResult(RESULT_OK,null);
	}
	
	private void cancellaTutti() {
		this.cancellaRReceivers();
		this.cancellaQReceivers();
	}
	
	private void cancellaRReceivers(){
		try {
			for (ResponseReceiver current : rrList) {
//			String debug=current.toString();
				getApplicationContext().unregisterReceiver(current);
				current.setActive(false);
			}
		} catch (Exception e) {
			Toast toast=Toast.makeText(HelpMeActivity.this, "Already stopped", Toast.LENGTH_LONG);
			toast.show();
		}
	}
	
	private void cancellaQReceivers(){
		try {
			for (QuestionReceiver current : qrList) {
				getApplicationContext().unregisterReceiver(current);
				current.setActive(false);
			}
		} catch (Exception e) {
			Toast toast=Toast.makeText(HelpMeActivity.this, "Already stopped", Toast.LENGTH_LONG);
			toast.show();
		}
	}

	@Override
	protected void onDestroy() {
//		cancellaQReceivers();
		super.onDestroy();
	}
	

	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		switch (id) {
		case 1:
			multiSpinner.cancel();
			break;
		case 2:
			Intent intent=new Intent(this, ConfigActivity.class);
			startActivity(intent);
			break;
		case 3:
			Bundle extras=this.readAnswers();
			Intent newintent=new Intent(this, AllQuestionsActivity.class);
			newintent.putExtras(extras);
			startActivity(newintent);
			break;
		case 4:
			remoteBroadcaster.sendToSuperPeer(new ServiceInfo(), Converter.UNSUBSCRIBE_FROM_ALL);
			cancellaRReceivers(); //non funziona
			break;
		case 5:
			cancellaQReceivers();
			remoteBroadcaster.sendToSuperPeer(new ServiceInfo(), Converter.RETRACT_FROM_ALL);
			break;
		default:
			break;
		}
		return true;
	}
	
	private Bundle readAnswers() {
		Bundle b=new Bundle();
		try {
			File file=new File(getExternalFilesDir(null), AllQuestionsActivity.filename);
			BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file)));
			String curr=br.readLine();
			while(curr!=null && curr!=""){
				if (curr.startsWith("###")){
					String quest=curr.substring(3);
					String risp="";
					String r=br.readLine();
					while (r!=null && r!=""){
						if (r.startsWith("###"))
							break;
						risp+=r+" ";
						r=br.readLine();
					}
					curr=r;
					ArrayList<String> lista=b.getStringArrayList(quest);
					if (lista==null || lista.size()==0)
						lista=new ArrayList<String>();
					lista.add(risp);
					b.putStringArrayList(quest, lista);
				}	
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return b;
	}



	private boolean checkConnection(){
		ConnectivityManager conMgr =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ninfo=conMgr.getActiveNetworkInfo();
		if (ninfo==null || !(ninfo.isConnected())) {
			AlertDialog.Builder builder = new AlertDialog.Builder(HelpMeActivity.this);
			builder.setMessage("Invalid Internet Connection.\nTry to enable WiFi.");
			builder.setCancelable(false);
			builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			               dialog.cancel();
			           }
			       });
			AlertDialog alert = builder.create();
			alert.show();
			return false;
		}
		else return true;
	}
	
	private boolean isServerSet(){
		if (remoteBroadcaster==null || remoteBroadcaster.getServerAddress()==null){
			AlertDialog.Builder builder = new AlertDialog.Builder(HelpMeActivity.this);
			builder.setMessage("This application needs a SuperPeer.\nPlease set its address in:\nMenu->Connection Configuration");
			builder.setCancelable(false);
			builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			               dialog.cancel();
			           }
			       });
			AlertDialog alert = builder.create();
			alert.show();
			return false;
		}
		else
		return true;
	}
	
	
	public void topicChosen(boolean chosen){
		this.setButtons(chosen);
	}



	private void setButtons(boolean b) {
		help.setEnabled(b);
		imhere.setEnabled(b);
//		help.setClickable(b);
//		imhere.setClickable(b);
	}



	
    
}